package cn.yuhan.simplediary.filter;

import cn.yuhan.simplediary.config.JwtTokenProvider;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * JWT 认证过滤器，从请求头中提取令牌，验证并设置认证上下文
 */
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends GenericFilter {

    private final JwtTokenProvider tokenProvider;
    private final UserDetailsService userDetailsService;

    private boolean isWhiteListed(String path) {
        return path.startsWith("/auth/")
                || path.equals("/toLogin")
                || path.startsWith("/view")
                || path.startsWith("/css/")
                || path.startsWith("/js/");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {


        HttpServletRequest request = (HttpServletRequest) req;
        String path = request.getRequestURI();
        // 白名单路径直接放行
        if (isWhiteListed(path)) {
            chain.doFilter(req, res);
            return;
        }

        String authHeader = request.getHeader("Authorization");



        // 检查请求头是否包含 Bearer Token
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);
            // 验证令牌有效性
            if (tokenProvider.validateToken(token)) {
                // 从令牌中获取用户名
                String username = tokenProvider.getUsername(token);
                // 加载用户详情
                var userDetails = userDetailsService.loadUserByUsername(username);
                // 构造认证对象
                var auth = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                // 设置 Spring Security 上下文为已认证
                SecurityContextHolder.getContext().setAuthentication(auth);
            }
        }
        // 放行请求链
        chain.doFilter(req, res);
    }
}